package myInterface

import (
	"fmt"
	"hash/crc32"
	"log"
	"time"

	"github.com/tarm/serial"
)

var (
	serilPort       *serial.Port
	err             error
	SerialStr       string
	SerialTime      int
	SerialFlag      bool = false
	serialbuf            = make(chan byte, 4096)
	SerilBufChan         = make(chan []byte, 1024)
	SerialWriteChan      = make(chan []byte, 1024)
	ChartsChan           = make(chan []byte, 1024)
)

func serialOpen(name string, buad int) (s *serial.Port, err error) {
	c := &serial.Config{Name: name, Baud: buad}

	s, err = serial.OpenPort(c)
	return
}

func serialRead(s *serial.Port) {
	recBuffer := make([]byte, 4096)
	for {
		n, err := s.Read(recBuffer)
		if err != nil {
			log.Println(err)
			break
		} else {
			// s := make([]byte, n)
			for i := 0; i < n; i++ {
				// s[i] = recBuffer[i]
				serialbuf <- recBuffer[i]
			}
			// SerilBufChan <- s
		}
	}
}

func data_analyse(data []byte) {
	fmt.Println(string(data))
	ChartsChan <- data
}

func dataProcess() {
	var (
		length     int
		flag       bool = false
		timeoutCnt int
		b          []byte
		crcB       []byte
	)

	go func() {
		for {
			//超时判断
			timeoutCnt++
			if (length-1) > len(serialbuf) && timeoutCnt >= 50 {
				flag = false
			}
			time.Sleep(time.Millisecond)
		}
	}()

	go func() {
		for {
			if flag {
				if len(serialbuf) >= length {
					flag = false

					b = b[0:0]
					crcB = crcB[0:0]
					for i := 0; i < (length - 4); i++ {
						b = append(b, <-serialbuf)
					}
					for i := (length - 4); i < length; i++ {
						crcB = append(crcB, <-serialbuf)
					}

					c := uint32(crcB[0])<<24 | uint32(crcB[1])<<16 |
						uint32(crcB[2])<<8 | uint32(crcB[3])<<0
					crc := crc32.ChecksumIEEE(b)
					if crc == c {
						data_analyse(b)
						flag = false
					} else {
						log.Println("crc error")
					}
				}
			} else {
				if <-serialbuf == 0x55 {
					if <-serialbuf == 0x55 {
						lengthH := int(<-serialbuf)
						lengthL := int(<-serialbuf)
						length = lengthH<<8 | lengthL
						flag = true
						timeoutCnt = 0
					}
				}
			}
		}
	}()
}
func dataProcess1() {
	buf := make([]byte, 4096)
	go func() {
		for {
			if len(serialbuf) > 0 {
				b := <-serialbuf
				if b == 0x0D {
					b = <-serialbuf
					if b == 0x0A {
						SerialTime = 0
						SerialStr += string(buf)
						SerialStr += "\r\n"
						buf = buf[0:0]
					}
				} else {
					buf = append(buf, b)
				}
			}
			SerialTime++
			time.Sleep(time.Microsecond * 1)
		}
	}()
}

func SerialInit(name string, buad int) error {
	serilPort, err = serialOpen(name, buad)
	SerialFlag = true
	dataProcess()
	// dataProcess1()

	go func() {
		for {
			SerialWrite(<-SerialWriteChan)
		}
	}()

	go serialRead(serilPort)
	return err
}

func SerialClose() error {
	if serilPort != nil {
		SerialFlag = false
		err = serilPort.Close()
		if err != nil {
			log.Println(err)
			return err
		} else {
			serilPort = nil
			log.Println("close")
		}
	}
	return nil
}

func SerialWrite(data []byte) error {
	if serilPort != nil {
		_, err = serilPort.Write(data)
		if err != nil {
			log.Println(err)
			return err
		}
	}
	return nil
}
